﻿namespace GeoFits
{
    /// <summary>
    /// 几何图形类：圆柱
    /// </summary>
    public class Cylinder : Geometry
    {
        #region 变量和属性
        private Point _center;
        private Vector _direct;
        /// <summary>
        /// 圆心
        /// </summary>
        /// <value>圆柱圆心</value>
        /// <remarks>从严格意义上讲，圆柱没有圆心。此处圆心指的圆柱中心线上的任意一点。</remarks>
        public Point Center
        {
            get
            {
                return _center;
            }
            set
            {
                _center = value;
            }
        }
        /// <summary>
        /// 半径
        /// </summary>
        /// <value>半径</value>
        public double Radius { get; set; }
        /// <summary>
        /// 方向向量
        /// </summary>
        /// <value>方向向量</value>
        /// <remarks>圆柱的方向向量。圆柱中心线的方向向量，圆心和方向向量就可以确定圆柱的中心线。</remarks>
        public Vector Direct
        {
            get
            {
                return _direct;
            }
            set
            {
                _direct = value.Normalize();
            }
        }
        #endregion
        /// <summary>
        /// 构造空圆柱
        /// </summary>
        /// <remarks>此时圆柱的所有参数都为空，需要设置后使用。</remarks>
        public Cylinder()
        {
            Center = new Point();
        }
        /// <summary>
        /// 构造圆柱
        /// </summary>
        /// <param name="pt">圆心</param>
        /// <param name="radius">半径</param>
        /// <param name="dir">圆柱的方向向量</param>
        public Cylinder(Point pt, Vector dir, double radius)
        {
            _center = pt;
            Radius = radius;
            _direct = dir.Normalize();
        }
        /// <summary>
        /// 点到圆柱面的距离
        /// </summary>
        /// <param name="pt">点</param>
        /// <returns>距离值：当在圆柱面内部时值为负值，在圆外部时为正值</returns>
        public double DistanceTo(Point pt)
        {
            Vector p = pt - Center;
            double sin = p.CrossProduct(Direct).Length / (p.Length * Direct.Length);
            return p.Length * sin - Radius;
        }

    }
}
